﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.UI;

namespace SharePoint.Contrib
{
    /// <summary>
    /// A generic task class to use with async tasks.
    /// </summary>
    /// <typeparam name="TResult">The result to return</typeparam>
    public abstract class AsyncTask<TResult>
    {
        public TResult Result { get; protected set; }
        delegate void AsyncTaskDelegate();
        private AsyncTaskDelegate task;
        public delegate void TaskFinished();
        private TaskFinished taskFinished;

        public AsyncTask()
        {

        }

        public PageAsyncTask CreateTask()
        {
            return new PageAsyncTask(this.OnBegin, this.OnEnd, this.OnTimeout, "PageAsyncTask", true);
        }

        public AsyncTask(TaskFinished taskFinishedHandler)
        {
            taskFinished = taskFinishedHandler;
        }

        public virtual IAsyncResult OnBegin(object sender, EventArgs e, AsyncCallback callback, object data)
        {
            task = new AsyncTaskDelegate(Execute);
            return task.BeginInvoke(callback, data);
        }

        public virtual void OnEnd(IAsyncResult result)
        {
            if (taskFinished != null)
            {
                taskFinished.Invoke();
            }

            task.EndInvoke(result);
        }

        public virtual void OnTimeout(IAsyncResult result)
        {
            Result = default(TResult);
        }

        public abstract void Execute();

    }
}
